The dataset for this activity is available in the rds files shared via Github (https://github.com/MarieAugerMethe/CANSSI_OTN_HMM_2023). It can used for our OTN/CANSSI meeting and shared for educational purposes with accreditation (C Willis, S Thorrold, C Braun; WHOI). It cannot be used for any publication without written permission. Please contact Ciara Willis (willisc@mit.edu) for more information.
Let’s load some of the packages needed.
library(ggplot2)
library(diveMove)
## Loading required package: stats4
## This is diveMove 1.6.1. For overview type vignette("diveMove")
library(tidyr)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
The biologging data of two swordfish in the North West Atlantic collected by Dr. Camrin Braun and team using MiniPAT tags (Wildlife Computers Inc.). Each fish’s data has been subset to ~2 months. The tag has collected depth, temperature (tag 110490 only), and position (lat/lon) data. Depth and temperature were sampled every 5 min (tag 110490) or 7.5 min (tag 110491). Position is reported once per day.
For each fish we have two time series: 1. the series files have the depth, light, and temperature (tag 110490 only), 2. the track files have the lat lon and associated error.
Let’s read and look at the data.
# Data found in the Data folder
#individual 11090
series_90 <- readRDS("Data/110490_series.rds")
track_90 <- readRDS("Data/110490_track.rds")
head(series_90)
## DateTime_local DateTime depth light temperature
## 2066 2011-09-22 00:05:00 2011-09-22 04:05:00 17.0 NA 22.5
## 2067 2011-09-22 00:10:00 2011-09-22 04:10:00 1.0 NA 22.5
## 2068 2011-09-22 00:15:00 2011-09-22 04:15:00 49.0 NA 19.5
## 2069 2011-09-22 00:20:00 2011-09-22 04:20:00 39.5 NA 20.8
## 2070 2011-09-22 00:25:00 2011-09-22 04:25:00 39.5 NA 19.8
## 2071 2011-09-22 00:30:00 2011-09-22 04:30:00 49.0 NA 20.2
head(track_90)
## DateTime latitude latitudeError longitude longitudeError
## 9 2011-09-22 20:00:00 41.14150 0.2260581 -49.11001 0.2481515
## 10 2011-09-23 20:00:00 41.27058 0.4562228 -49.08276 0.6751229
## 11 2011-09-24 20:00:00 41.04068 0.4298305 -48.84454 0.3868666
## 12 2011-09-25 20:00:00 40.64077 0.4331831 -49.41309 0.3376429
## 13 2011-09-26 20:00:00 40.53024 0.3841507 -49.98148 0.3309471
## 14 2011-09-27 20:00:00 40.15149 0.6022806 -50.38425 0.6412108
## tz localHour
## 9 Etc/GMT+3 17
## 10 Etc/GMT+3 17
## 11 Etc/GMT+3 17
## 12 Etc/GMT+3 17
## 13 Etc/GMT+3 17
## 14 Etc/GMT+3 17
#individual 11091
series_91 <- readRDS("Data/110491_series.rds")
track_91 <- readRDS("Data/110491_track.rds")
head(series_91)
## DateTime_local DateTime depth light
## 20977 2012-01-02 02:00:00 2012-01-02 06:00:00 17.5 NA
## 20978 2012-01-02 02:07:30 2012-01-02 06:07:30 23.5 NA
## 20979 2012-01-02 02:15:00 2012-01-02 06:15:00 17.5 NA
## 20980 2012-01-02 02:22:30 2012-01-02 06:22:30 23.5 NA
## 20981 2012-01-02 02:30:00 2012-01-02 06:30:00 23.5 NA
## 20982 2012-01-02 02:37:30 2012-01-02 06:37:30 23.5 NA
head(track_91)
## DateTime latitude latitudeError longitude longitudeError
## 110 2012-01-01 19:00:00 33.74526 1.2861760 -58.91076 1.5771658
## 111 2012-01-02 19:00:00 33.59312 0.9251196 -58.84867 1.3784056
## 112 2012-01-03 19:00:00 33.24697 1.0949812 -58.77419 1.1740887
## 113 2012-01-04 19:00:00 32.96088 0.7772091 -58.65916 0.4855588
## 114 2012-01-05 19:00:00 32.97567 0.7019704 -58.27720 0.8291009
## 115 2012-01-06 19:00:00 32.79749 0.7019704 -58.07182 0.8291009
## tz localHour
## 110 Etc/GMT+4 15
## 111 Etc/GMT+4 15
## 112 Etc/GMT+4 15
## 113 Etc/GMT+4 15
## 114 Etc/GMT+4 15
## 115 Etc/GMT+4 15
As we can see, the series datasets contain these variables:
The track datasets contain these variables:
The main movement variable we will model is depth. There is some missing data.
Let’s quickly visualize the data.
# Load world map
world <- map_data('world')
ggplot(series_90, aes(DateTime, depth, colour = temperature))+
geom_point()+
geom_line() +
scale_color_viridis_c()+
scale_y_reverse()+
labs(colour = "Temp")
ggplot() +
theme(legend.position = c(.9,.2),
panel.grid=element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank()
)+
geom_polygon(data = world, aes(x=long, y = lat, group = group)) +
coord_fixed(xlim=c(-90,-30), ylim=c(10,50), ratio=1.3) +
xlab('') + ylab('') +
geom_point(data = track_90, aes(x=longitude, y=latitude, colour = DateTime))
ggplot(series_91, aes(DateTime, depth)) +
geom_point() +
geom_line() +
scale_color_viridis_c() +
scale_y_reverse()
ggplot() +
theme(legend.position = c(.9,.2),
panel.grid=element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank()
)+
geom_polygon(data = world, aes(x=long, y = lat, group = group)) +
coord_fixed(xlim=c(-90,-30), ylim=c(10,50), ratio=1.3) +
xlab('') + ylab('') +
geom_point(data = track_91, aes(x=longitude, y=latitude, colour = DateTime))
Here is a quick way to get to isolate and sumarize dives using
diveMove. First since there is missing data I regularized
the dataset.
# Regularize data
dive_90 <- series_90 %>%
# regularise time series by 5 min
summarise(DateTime = seq(first(DateTime), last(DateTime), by = 5*60)) %>%
# merge regularised time with original dive
left_join(series_90, by = c("DateTime"))
Create a TDR object from diveMove.
dive_90 <- createTDR(time = dive_90$DateTime, depth = dive_90$depth, file = "Data/110490_series.rds")
plotTDR(dive_90)
You can look at dive phases and calibrate for offset using functions
such as calibrateDepth. Here I just used a 0 offset, but
might want to look into the details to see if approriate.
The threshold I use to separate dives is 10 m. Changing this threshold will change the results.
dive_90_cal <- calibrateDepth(dive_90,
zoc.method = "offset", offset = 0, dive.thr = 10)
## Record is truncated at the beginning and at the end
## 55 phases detected
## 371 dives detected
plotTDR(dive_90_cal)
Here are some quick summary statistics. You may want to think about how the missing data could affect the results.
stats_90 <- diveStats(dive_90_cal)
colnames(stats_90)
## [1] "begdesc" "enddesc" "begasc" "desctim"
## [5] "botttim" "asctim" "divetim" "descdist"
## [9] "bottdist" "ascdist" "bottdep.mean" "bottdep.median"
## [13] "bottdep.sd" "maxdep" "postdive.dur" "descD.min"
## [17] "descD.1stqu" "descD.median" "descD.mean" "descD.3rdqu"
## [21] "descD.max" "descD.sd" "bottD.min" "bottD.1stqu"
## [25] "bottD.median" "bottD.mean" "bottD.3rdqu" "bottD.max"
## [29] "bottD.sd" "ascD.min" "ascD.1stqu" "ascD.median"
## [33] "ascD.mean" "ascD.3rdqu" "ascD.max" "ascD.sd"
head(stats_90)
## begdesc enddesc begasc desctim botttim
## 1 2011-09-22 04:05:00 2011-09-22 04:05:00 2011-09-22 04:05:00 150 NA
## 2 2011-09-22 04:15:00 2011-09-22 04:20:00 2011-09-22 04:30:00 450 600
## 3 2011-09-22 04:45:00 2011-09-22 04:50:00 2011-09-22 04:55:00 450 300
## 4 2011-09-22 05:05:00 2011-09-22 05:05:00 2011-09-22 05:15:00 150 300
## 5 2011-09-22 05:30:00 2011-09-22 05:30:00 2011-09-22 05:40:00 150 300
## 6 2011-09-22 06:00:00 2011-09-22 06:00:00 2011-09-22 06:00:00 150 NA
## asctim divetim descdist bottdist ascdist bottdep.mean bottdep.median
## 1 150 300 17.0 NA 17 NA NA
## 2 150 1200 49.0 9.5 49 42.66667 39.50
## 3 150 900 21.5 3.0 14 15.50000 15.50
## 4 150 600 39.5 25.5 14 26.75000 26.75
## 5 150 600 21.5 0.0 49 49.00000 49.00
## 6 150 300 49.0 NA 49 NA NA
## bottdep.sd maxdep postdive.dur descD.min descD.1stqu descD.median
## 1 NA 17.0 0 13.52020458 16.35273705 18.42844752
## 2 5.484828 49.0 300 0.04506415 0.06242384 0.06826952
## 3 2.121320 21.5 0 0.02519001 0.02637487 0.02855108
## 4 18.031223 39.5 300 NA NA NA
## 5 0.000000 49.0 600 NA NA NA
## 6 NA 49.0 300 38.97000143 47.13435973 53.11728992
## descD.mean descD.3rdqu descD.max descD.sd bottD.min bottD.1stqu
## 1 17.67162552 19.74733599 20.30940247 3.049505749 NA NA
## 2 0.06550294 0.07151864 0.07730198 0.010634440 -0.002751729 0.005492982
## 3 0.02900677 0.03158150 0.03339358 0.003203254 -0.026545563 -0.016871213
## 4 NaN NA NA NA -0.098462574 -0.059718351
## 5 NaN NA NA NA -0.060840116 0.049084835
## 6 50.93586180 56.91879199 58.53886593 8.789751864 NA NA
## bottD.median bottD.mean bottD.3rdqu bottD.max bottD.sd ascD.min
## 1 NA NaN NA NA NA -20.30940247
## 2 0.017171866 0.0168928290 0.027343387 0.03815693 0.01558522 -0.22082939
## 3 -0.006789868 -0.0065804547 0.003500891 0.01380348 0.01739945 -0.05406899
## 4 -0.014112721 0.0008843567 0.064369035 0.08998200 0.07002814 NA
## 5 0.068280087 0.0547327810 0.086605569 0.09807132 0.04885718 -0.20098071
## 6 NA NaN NA NA NA -58.53886593
## ascD.1stqu ascD.median ascD.mean ascD.3rdqu ascD.max ascD.sd
## 1 -17.86268103 -10.91707326 -8.83581276 -1.38565699 8.31394195 10.730961726
## 2 -0.20467382 -0.17524393 -0.16210499 -0.13267511 -0.07710271 0.063706359
## 3 -0.05241717 -0.04922966 -0.04761568 -0.04442817 -0.03793438 0.007176099
## 4 NA NA NaN NA NA NA
## 5 -0.19226143 -0.17544090 -0.16705151 -0.15023098 -0.11634352 0.037640665
## 6 -51.48655121 -31.46685823 -25.46793090 -3.99395250 23.96371502 30.930419091
You can see that you get a lot of information per dive, e.g. bottom time, maximum depth, etc. Here it’s only for individual 90, but this could be easily reproduce for individual 91.
Here is a quick plot of max depth through time
ggplot(stats_90, aes(x=begdesc, y=-1*maxdep)) +
xlab('Start of the dive') + ylab('Max depth of the dive') +
geom_point() +
geom_line()
The goals are (1) to provide a road map of how to tackle the questions listed below, (2) attempt to complete at least the first step of your road map, and (3) provide interpretation of the results. Make a quick 5-minute presentation explaining what your team did.
The goal of this project is to describe the diel vertical migration (DVM) behaviour of swordfish and identify deviations from DVM. DVM is a pattern of vertical habitat use where nights are spent in the surface ocean and days in the mesopelagic (~600 m). Swordfish typically follow a clear DVM, but occasionally 1) briefly come up to surface waters during the daytime or 2) dive unusually deep (to ~1000m or more). The typical DVM pattern is presumably due to predation on migrating communities of mesopelagic fish & invertebrates. The daytime surface water use (i.e., basking) is presumably to warm up. The purpose of the occasional deep dives is unclear, but may be linked to navigation.
Areas of exploration: